<template>
  <a-row  class="my-search-form">
    <a-form
      ref="formRef"
      :model="formState"
      :label-col="labelCol"
      :wrapper-col="wrapperCol"
      labelAlign="left"
      :rules="rules"
      layout="horizontal">
      <template v-for="(item, index) in list || []">
        <!-- 插槽 -->
        <template v-if=" item.type === 'slot' ">
          <a-col :span="24" :key="index">
            <slot
              :name="item.prop"
              :index="index"
              :item="item"
              :formState="formState"
              :list="list"
              ></slot>
          </a-col>
        </template>
        <template v-if=" item.type === 'input' ">
          <a-col :span="24" :key="index">
            <a-form-item :label="item.label" :name="item.prop">
              <a-input
                v-model:value="formState[item.prop]"
                allow-clear
                :placeholder=" item.placeholder || '请输入' + item.label  "
                v-bind="item.meta || {}"/>
            </a-form-item>
          </a-col>
        </template>
        <template v-else-if=" item.type === 'textarea' ">
          <a-col :span="24" :key="index">
            <a-form-item :label="item.label" :name="item.prop">
              <a-input
                v-model:value="formState[item.prop]"
                allow-clear
                :placeholder=" item.placeholder || '请输入' + item.label  "
                v-bind="item.meta || {}"/>
            </a-form-item>
          </a-col>
        </template>
        <template v-else-if=" item.type === 'input-number' ">
          <a-col :span="24" :key="index">
            <a-form-item :label="item.label" :name="item.prop">
              <a-input-number v-model:value="formState[item.prop]" :min="1" :max="10" />
            </a-form-item>
          </a-col>
        </template>
        <template v-else-if=" item.type === 'select' ">
          <a-col :span="24" :key="index">
            <a-form-item :label="item.label" :name="item.prop">
              <a-select
                v-model:value="formState[item.prop]"
                allowClear
                :placeholder=" item.placeholder || '请选择' + item.label  "
                v-bind="item.meta || {}">
                <a-select-option
                  v-for="(sItem, sIndex) in options[item.prop] || []"
                  :value="sItem.dicValue">{{ sItem.dicLabel }}</a-select-option>
              </a-select>
            </a-form-item>
          </a-col>
        </template>
        <template v-else-if=" item.type === 'cascader' ">
          <a-col :span="24" :key="index">
            <a-form-item :label="item.label" :name="item.prop">
              <a-cascader
                v-model:value="formState[item.prop]"
                :options="item.options"
                :placeholder=" item.placeholder || '请选择' + item.label  "
                v-bind="item.meta || {}"/>
            </a-form-item>
          </a-col>
        </template>
        <template v-else-if=" item.type === 'radio' ">
          <a-col :span="24" :key="index">
            <a-form-item :label="item.label" :name="item.prop">
              <a-radio-group v-model:value="formState[item.prop]">
                <a-radio :value="sItem.dicValue" v-for="(sItem, sIndex) in options[item.prop] || []">{{ sItem.dicLabel }}</a-radio>
              </a-radio-group>
            </a-form-item>
          </a-col>
        </template>
        <template v-else-if=" item.type === 'checkbox' ">
          <a-col :span="24" :key="index">
            <a-form-item :label="item.label" :name="item.prop">
              <a-checkbox v-model:checked="formState[item.prop]" >是</a-checkbox>
            </a-form-item>
          </a-col>
        </template>
        <template v-else-if=" item.type === 'checkbox-group' ">
          <a-col :span="24" :key="index">
            <a-form-item :label="item.label" :name="item.prop">
              <a-checkbox-group v-model:value="formState[item.prop]" :name="item.prop">
                  <span v-for="(sItem, sIndex) in options[item.prop] || []" :key="sIndex">
                    <a-checkbox
                      :value="sItem.dicValue">{{ sItem.dicLabel }}</a-checkbox>
                  </span>
              </a-checkbox-group>
            </a-form-item>
          </a-col>
        </template>
        <template v-else-if=" item.type === 'orgId' ">
          <a-col :span="24" :key="index">
            <a-form-item :label="item.label" :name="item.prop">
              <a-cascader
                v-model:value="formState[item.prop]"
                :options="options[item.prop] || []"
                :placeholder=" item.placeholder || '请选择' + item.label  "
                :fieldNames="{ label: 'name', value: 'id', children: 'children' }"
                :show-search="{ filter: cascaderFilter }"
                v-bind="item.meta || {}"/>
            </a-form-item>
          </a-col>
        </template>
        <template v-else-if=" item.type === 'upload' ">
          <a-col :span="24" :key="index">
            <a-form-item :label="item.label" :name="item.prop">
              <my-upload v-model:file-list="formState[item.prop]" v-bind="item.meta || {}"></my-upload>
            </a-form-item>
          </a-col>
        </template>
      </template>
    </a-form>
  </a-row>
</template>

<script>
import { computed, reactive, ref, toRef } from 'vue'
import { useStore } from  'vuex'

export default {
  props: {
    formList: {
      type: Array,
      default: () => []
    },
    initialValue: {         //  这个也是外层传入的 默认值， 具有 最高 优先级， 比 配置文件中传入的默认值优先级 更高
      type: Object,
      default: () => ({})
    }
  },
  setup({ formList, initialValue }, {expose}) {

    const formRef = ref(null)
    const store = useStore()

    const formConfig = reactive({
      list: $g.cloneDeep(formList),       // 控件的 配置项 数组
      options: {},
      formState: {},
      rules: {},
      initialDefaultValue: {}             //  初始化的 默认值 -- 比如 筛选 重置后 需要 填充这个默认值
    })

    const orgList = computed(() => store.state.orgList)

    const itemTypeList = ['cascader', 'checkbox-group']
    const initRule = (item = {}) => {        //  设置 控件 的 校验规则
      const { validate = {}, type, meta = {} } = item
      const { mode } = meta   //  mode = 'multiple'  则为  多选

      const cItem = {required: false, trigger: 'change'}

      if( itemTypeList.indexOf(type) >= 0 || (type === 'select' && mode === 'multiple') ){
        cItem.type = 'array'      // 如果 绑定的 数据 格式是 数组 则 必须 设置 校验规则 type 为 array
      }

      if( type === 'checkbox' ){
        cItem.type = 'boolean'
      }

      const { fn } = validate
      if( typeof fn === 'function' ){
        formConfig.rules[item.prop] = [Object.assign(cItem, validate,{ validator: item.validate.fn.bind('', formConfig) })]
      } else if(Object.keys(validate).length > 0) {
        formConfig.rules[item.prop] = [Object.assign(cItem, {message: item.label + '是必须项'}, validate)]
      }
    }

    const initDefaultValue = (item = {}) => {
      if( 'defaultValue' in item ){
        formConfig.formState[item.prop] = item.defaultValue
        formConfig.initialDefaultValue[item.prop] = $g.cloneDeep(item.defaultValue)           //  初始化 值 保存 一份深拷贝的数据
      }
    }

    const initFormData = () => {
      const dictStringList = []
      formConfig.list.forEach(item => {

        initRule(item)          // 初始化 规则
        initDefaultValue(item)   //  初始化 默认值

        if( item.type === 'orgId' ){
          console.log('orgList ====================', orgList)
          formConfig.options[item.prop] = orgList.value
        }else if( Array.isArray(item.options) ){        // 如果是 写死的  数组 数据  则直接赋值
          formConfig.options[item.prop] = item.options
        }else if( typeof item.options === 'function' ){        //   如果是 函数 调用返回数据，则必须返回 Promise
          item.options().then(v => formConfig.options[item.prop] = item.options)
        }else if( typeof item.options === 'string' ){   // 如果是 字符串， 则 将 所有 字符串 收集 起来， 统一 请求接口 获取数据
          formConfig.options[item.options] = item.options
          dictStringList.push(item.options)
        }
      })

      // 然后发请求 获取  字典
      $g.getDicts(dictStringList).then(dictRes => {
        formConfig.list.forEach(item => {
          if( typeof item.options === 'string' && item.options in dictRes ){
            formConfig.options[item.prop] = dictRes[item.options]
          }
        })
      })

      // 继续 设置 初始化的 默认值，  外层 传入的 initialValue  具有 最高 优先级 -- 优先取 外层 传入的 默认值
      Object.keys(initialValue).forEach(r => {
        formConfig.formState[r] = initialValue[r]
        formConfig.initialDefaultValue[r] = $g.cloneDeep(initialValue[r])           //  初始化 值 保存 一份深拷贝的数据
      })
    }

    const onSubmit = () => {
      console.log('submit!', toRaw(formState));
    }

    const validate = (callback) => {
      console.log('formConfig.formState  ===== ')
      console.log(formConfig.formState)
      formRef.value.validate().then(formState => {
        typeof callback === 'function' && callback(formConfig.formState)
      }).catch(error => {
        console.log('error', error);
      })
    }

    const resetFields = () => {
      formConfig.formState = $g.cloneDeep(formConfig.initialDefaultValue)
      formRef.value.resetFields()
    }

    const cascaderFilter = (inputValue, path) => {
      return path.some(option => option.name.toLowerCase().indexOf(inputValue.toLowerCase()) > -1);
    }

    const options = [{
      value: 'zhejiang',
      label: 'Zhejiang',
      children: [{
        value: 'hangzhou',
        label: 'Hangzhou',
        children: [{
          value: 'xihu',
          label: 'West Lake',
        }],
      }],
    }, {
      value: 'jiangsu',
      label: 'Jiangsu',
      children: [{
        value: 'nanjing',
        label: 'Nanjing',
        children: [{
          value: 'zhonghuamen',
          label: 'Zhong Hua Men',
        }],
      }],
    }]

    const treeData = [{
      title: 'parent 1',
      value: 'parent 1',
      children: [{
        title: 'parent 1-0',
        value: 'parent 1-0',
        children: [{
          title: 'my leaf',
          value: 'leaf1',
        }, {
          title: 'your leaf',
          value: 'leaf2',
        }],
      }, {
        title: 'parent 1-1',
        value: 'parent 1-1',
      }],
    }]

    expose({
      validate,
      resetFields,
      formConfig
    })

    initFormData()      // 初始化 基础 数据

    const handleChange = (a, b, c) => {
      console.log(a, b, c)
    }

    const test = () => {
      formConfig.formState.attach = []
    }

    return {
      options,
      treeData,
      formRef,
      labelCol: {
        style: {
          width: '140px',
        },
        // span: 4,
      },
      wrapperCol: {
        // span: 14,
        // width: '200px',
      },
      formConfig,
      rules: toRef(formConfig, 'rules'),
      options: toRef(formConfig, 'options') ,
      list: toRef(formConfig, 'list') ,
      formState: toRef(formConfig, 'formState'),
      cascaderFilter,
      handleChange,
      headers: {Authorization: $g.getToken()},
      test
    }
  },
}
</script>

<style scoped lang="less">
.my-search-form{
  /deep/.ant-form-item{
    margin-bottom: 18px;
  }
  // /deep/.ant-form-item-with-help{
  //   margin-bottom: 18px;
  // }
  /deep/.ant-form-item-explain{
    font-size: 12px;
    position: absolute;
    top: 100%;
    left: 0;
    min-height: auto;
  }
}
</style>